package com.gaojun;

import java.awt.Desktop;
import java.awt.GraphicsEnvironment;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.TargetDataLine;
import javax.swing.filechooser.FileSystemView;

import com.gaojun.tool.Constant;
import com.gaojun.tool.PropertiesUtil;

import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.geometry.Rectangle2D;
import javafx.geometry.Side;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Button;
import javafx.scene.control.ColorPicker;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.Spinner;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.control.Tooltip;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.stage.DirectoryChooser;
import javafx.stage.FileChooser;
import javafx.stage.Modality;
import javafx.stage.Screen;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import sun.audio.AudioStream;
import sun.security.krb5.internal.PAEncTSEnc;

/**
 * 录音
 * @author gj
 *
 */
public class AudioRecording extends Stage {

	private static final int WIDTH = 400;
	private static final int HEIGHT = 60;

	private String DEFAULT_FILE_PATH = ""; // 默认存放路径

	private Label lblTime = null;
	private AudioRecord audio = null; // 录屏
	// 计数线程
	private CountingThread thread = null;
	// 记录程序开始时间
	private long programStart = 0;
	// 程序一开始就是暂停的
	private long pauseStart = 0;
	// 程序暂停的总时间
	private long pauseCount = 0;
	private String currentFilePath = ""; // 当前路径
	private double xOffset = 0;
	private double yOffset = 0;
	private boolean isHaveDevice = false; // 是否有录音设备

	public AudioRecording() {
		String style = "-fx-background-color:#00000000";

		/******* 分割线：设置弹出窗的一些样式 ***********/
		this.initStyle(StageStyle.TRANSPARENT); // 设置弹出窗为透明
		this.setWidth(WIDTH);
		this.setHeight(260);
		Rectangle2D primaryScreenBounds = Screen.getPrimary().getVisualBounds();
		this.setX((primaryScreenBounds.getWidth() - WIDTH) / 2);
		this.setY(primaryScreenBounds.getHeight() - 260);
		BorderPane borderPane = new BorderPane();
		borderPane.setStyle(style);
		borderPane.setPrefSize(500, 260);

		// this.getIcons().add(new Image(Constant.LOGO));
		/******* 分割线：设置弹出窗的一些样式 ***********/

		Button start = new Button(""); // 开始按钮
		Button play = new Button(""); // 播放按钮
		Button hidden = new Button(""); // 关闭弹窗
		Button stop = new Button("");
		Button set = new Button("");
		Button home = new Button("");

	
		/******* 分割线：设置开始录课按钮的一些样式 ********/
		start.setTooltip(new Tooltip("录音"));
		start.setGraphic(new ImageView(new Image("res/images/record/record.png")));
		start.setLayoutX(6);
		start.setLayoutY(14);
		start.setStyle(style);
		/******* 分割线：设置开始录课按钮的一些样式 ********/
		lblTime = new Label("00:00:00");
		lblTime.setStyle("-fx-background-color:#00000000");
		lblTime.setFont(Font.font("KaiTi", FontWeight.BOLD, 16));
		lblTime.setTextFill(Color.WHITE);
		lblTime.setLayoutX(52);
		lblTime.setLayoutY(23);
		lblTime.setPrefSize(80, 25);

		stop.setTooltip(new Tooltip("停止"));
		stop.setGraphic(new ImageView(new Image("res/images/record/stop.png")));
		stop.setLayoutX(131);
		stop.setLayoutY(14);
		stop.setStyle(style);

		/******** 分割线：设置播放按钮的一些样式 *********/
		play.setTooltip(new Tooltip("播放"));
		play.setGraphic(new ImageView(new Image("res/images/record/play.png")));
		play.setLayoutX(183);
		play.setLayoutY(14);
		play.setStyle(style);
		/******** 分割线：设置播放按钮的一些样式 *********/
		set.setTooltip(new Tooltip("设置"));
		set.setGraphic(new ImageView(new Image("res/images/record/set.png")));
		set.setLayoutX(236);
		set.setLayoutY(14);
		set.setStyle(style);

		home.setTooltip(new Tooltip("返回主页"));
		home.setGraphic(new ImageView(new Image("res/images/record/home.png")));
		home.setLayoutX(294);
		home.setLayoutY(14);
		home.setStyle(style);

		/********** 分割线：设置关闭按钮的一些样式 ********/
		hidden.setTooltip(new Tooltip("隐藏控制栏"));
		hidden.setGraphic(new ImageView(new Image("res/images/record/hidden.png")));
		hidden.setLayoutX(338);
		hidden.setLayoutY(14);
		hidden.setStyle(style);
		/********** 分割线：设置关闭按钮的一些样式 ********/

		// 开始录课

		start.setOnAction(e -> {
			if (start.getTooltip().getText().equals("录音")) {
				try {
					if (audio == null) {
						DEFAULT_FILE_PATH = Constant.SAVE_PATH;
						isHaveDevice = isHaveDevice();
						if (!isHaveDevice) {
				            Alert alert = new Alert(AlertType.INFORMATION);
				            alert.titleProperty().set("提示");
				            alert.headerTextProperty().set("请连接麦克风！！！");
				            alert.showAndWait();
							return;
						}
						thread = new CountingThread();
						thread.start();
						programStart = System.currentTimeMillis();
						pauseStart = programStart;
						File directory = new File(DEFAULT_FILE_PATH);
						if (!(directory.exists()) && !directory.isDirectory()) {
							directory.mkdirs();
						}
						SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");// 设置日期格式
						currentFilePath = DEFAULT_FILE_PATH + File.separatorChar + df.format(new Date());
						pauseCount += (System.currentTimeMillis() - pauseStart);
						audio = new AudioRecord(new File(currentFilePath+".mp3"));
					}
					audio.capture();
					start.setGraphic(new ImageView(new Image("res/images/record/puash.png")));
					start.setTooltip(new Tooltip("暂停"));
					pauseCount += (System.currentTimeMillis() - pauseStart);
					thread.stopped = false;
				} catch (Exception ex) {
					// TODO: handle exception
					thread.stopped = true;
					this.show();
				}

			} else {
				Alert alert = new Alert(AlertType.INFORMATION);
	            alert.titleProperty().set("提示");
	            alert.headerTextProperty().set("正在录音请先停止！！！");
	            alert.showAndWait();
			}

		});

		// 调用播放器播放视频
		play.setOnAction(e -> {
			try {
				Desktop.getDesktop().open(new File(currentFilePath + ".mp4"));
				// System.gc();
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}

		});
		// 停止
		stop.setOnAction(e -> {
			if (audio!=null) {
				start.setGraphic(new ImageView(new Image("res/images/record/record.png")));
				start.setTooltip(new Tooltip("录屏"));
				lblTime.setText("00:00:00");
				programStart = 0;
				pauseStart = 0;
				pauseCount = 0;
				audio.save();;
				thread.stopped = true;
				thread = null;
				audio = null;
			}
			
		});

		set.setOnAction(e -> {
			showSetting(borderPane);
		});

		// 关闭
		hidden.setOnAction(e -> {
			this.setIconified(true);
		});

		home.setOnAction(e -> {
			if (audio!=null) {
				audio.save();;
				thread.stopped = true;
				thread = null;
				audio = null;
			}
			MultimediaProcessingMain main = new MultimediaProcessingMain();
			try {
				main.start(new Stage());
			} catch (Exception e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			this.close();
		});

		Pane paneButton = new Pane();
		paneButton.setPrefSize(WIDTH, HEIGHT);
		paneButton.setStyle("-fx-background-color:#000;");
		paneButton.getChildren().addAll(start, lblTime, stop, play, set, home, hidden);

		// 窗口拖动
		this.addEventHandler(MouseEvent.ANY, new EventHandler<MouseEvent>() {

			@Override
			public void handle(MouseEvent event) {
				// TODO Auto-generated method stub
				event.consume();
				if (event.getEventType() == MouseEvent.MOUSE_PRESSED) {
					xOffset = event.getSceneX();
					yOffset = event.getSceneY();
				} else if (event.getEventType() == MouseEvent.MOUSE_DRAGGED) {
					AudioRecording.this.setX(event.getScreenX() - xOffset);
					if (event.getScreenY() - yOffset < 0) {
						AudioRecording.this.setY(0);
					} else {
						AudioRecording.this.setY(event.getScreenY() - yOffset);
					}
				}
			}
		});

		borderPane.setBottom(paneButton);
		Scene scene = new Scene(borderPane);
		scene.setFill(null);
		this.getIcons().add(new Image("res/image/stage/logo.png"));
		this.setScene(scene);
	}

	


	
	/**
	 * 设置
	 * @param borderPane
	 */
	private void showSetting(BorderPane borderPane) {
		if (borderPane.getCenter() != null) {
			borderPane.setCenter(null);
			return;
		}
		getParams();
		Pane pane = new Pane();
		pane.setPrefSize(400, 200);
		pane.setStyle("-fx-background-color:#000");
		TabPane tabPane = new TabPane();
		tabPane.setPrefSize(400, 178);
		tabPane.setSide(Side.LEFT);
		tabPane.setStyle("-fx-background-color:#000");
		tabPane.setTabClosingPolicy(TabPane.TabClosingPolicy.UNAVAILABLE);

		final Tab tab1 = new Tab();
		tab1.setText("基础设置");
		tab1.setStyle("-fx-font-size:16px");
		Pane panebasis = new Pane();
		panebasis.setPrefSize(380, 178);
		Label lblSavePath = new Label("存储位置：");
		lblSavePath.setTextFill(Color.WHITE);
		lblSavePath.setFont(Font.font(16));
		lblSavePath.setLayoutX(5);
		lblSavePath.setLayoutY(75);
		TextField txtPath = new TextField();
		txtPath.setFont(Font.font(16));
		txtPath.setPrefSize(220, 35);
		txtPath.setLayoutX(75);
		txtPath.setLayoutY(65);
		txtPath.setText(Constant.SAVE_PATH);

		Button btnSet = new Button("设置");
		btnSet.setFont(Font.font(16));
		btnSet.setTextFill(Color.WHITE);
		btnSet.setStyle("-fx-background-color:#808a87");
		btnSet.setLayoutX(300);
		btnSet.setLayoutY(50);
		btnSet.setOnAction(e -> {
			DirectoryChooser directoryChooser = new DirectoryChooser();
			File file = directoryChooser.showDialog(this);
			if (file != null) {
				txtPath.setText(file.getPath().toString());
			}

		});

		Button btnView = new Button("浏览");
		btnView.setFont(Font.font(16));
		btnView.setTextFill(Color.WHITE);
		btnView.setStyle("-fx-background-color:#808a87");
		btnView.setLayoutX(300);
		btnView.setLayoutY(90);
		btnView.setOnAction(e -> {
			try {
				Desktop.getDesktop().open(new File(txtPath.getText().toString()));
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		});

		panebasis.getChildren().addAll(lblSavePath, txtPath, btnSet, btnView);
         tab1.setContent(panebasis);
		tabPane.getTabs().addAll(tab1);
		tabPane.setStyle("-fx-background-color:#000");

		Button btnConfirm = new Button("确定");
		btnConfirm.setFont(Font.font(16));
		btnConfirm.setTextFill(Color.WHITE);
		btnConfirm.setStyle("-fx-background-color:#808a87");
		btnConfirm.setLayoutX(220);
		btnConfirm.setLayoutY(178);
		btnConfirm.setOnAction(e -> {
			Constant.SAVE_PATH = txtPath.getText().toString();
			Map<String, String> map = new HashMap<>();
			map.put("SAVE_PATH", txtPath.getText().toString()); // 激活标致
			PropertiesUtil.setValue(System.getProperty("user.dir") + File.separatorChar + "config/savepath.properties",
					map);
			borderPane.setCenter(null);
		});

		Button btnCancle = new Button("取消");
		btnCancle.setFont(Font.font(16));
		btnCancle.setTextFill(Color.WHITE);
		btnCancle.setStyle("-fx-background-color:#808a87");
		btnCancle.setLayoutX(300);
		btnCancle.setLayoutY(178);
		btnCancle.setOnAction(e -> {
			borderPane.setCenter(null);
		});
		pane.getChildren().addAll(tabPane, btnConfirm, btnCancle);
		borderPane.setCenter(pane);
	}

	/**
	 * 获取参数
	 */
	private void getParams() {
		Properties properties = new Properties();

		// 使用InPutStream流读取properties文件，获取服务器的IP和端口号
		try {
			BufferedReader bufferedReader = new BufferedReader(
					new FileReader(System.getProperty("user.dir") + File.separatorChar + "config/savepath.properties"));
			properties.load(bufferedReader);

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		// 获取key对应的value值
		String savePath = properties.getProperty("SAVE_PATH").toString();
		if (!"".equals(savePath)) {
			Constant.SAVE_PATH = savePath;
		}

	}

	/**
	 * 判断是否有录音设备
	 * 
	 * @return true or false
	 */
	private Boolean isHaveDevice() {
		Boolean result = false;
		AudioFormat audioFormat = new AudioFormat(44100.0F, 16, 2, true, false);
		DataLine.Info dataLineInfo = new DataLine.Info(TargetDataLine.class, audioFormat);
		try {
			TargetDataLine line = (TargetDataLine) AudioSystem.getLine(dataLineInfo);
			result = true;
			line.stop();
			line.close();
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			result = false;
		}
		return result;
	}

	/**
	 * 计时器
	 * 
	 * @author gj
	 *
	 */
	private class CountingThread extends Thread {

		volatile public boolean stopped = true; // 停止标志

		private CountingThread() {
			setDaemon(true);
		}

		@Override
		public synchronized void run() {
			while (true) {
				if (!stopped) {
					long elapsed = System.currentTimeMillis() - programStart - pauseCount; // 当前录制时间
					Platform.runLater(() -> {
						lblTime.setText(format(elapsed));
					});
				}

				try {
					sleep(1000); // 1秒更新一次显示
				} catch (InterruptedException e) {
					e.printStackTrace();
					break;
				}
			}
		}

		// 将毫秒数格式化
		private String format(long elapsed) {
			int hour, minute, second;

			elapsed = elapsed / 1000;

			second = (int) (elapsed % 60);
			elapsed = elapsed / 60;

			minute = (int) (elapsed % 60);
			elapsed = elapsed / 60;

			hour = (int) (elapsed % 60);

			return String.format("%02d:%02d:%02d", hour, minute, second);
		}
	}

}
